<?php 
class DomArMiscTestCase extends DomArTestUnitTestCase {

	// ---------------------------------------------------------------
	// TESTS
	// ---------------------------------------------------------------
	
	public function testAccessByReference() {
		$item = new DomArTestClass_BasicFields( 'tekst', true );
		$value = &$item->access('text');
		$this->assertEqual($value, 'tekst' );
		$value = 'newTekst';
		$this->assertEqual($value, 'newTekst' );
		$this->assertEqual($item->text, 'newTekst' );
		
		// this is not supported
		//$value = &$item->text;
		//$value = 'newTekst2';
		//$this->assertEqual($value, 'newTekst2' );
		//$this->assertEqual($item->text, 'newTekst2' );
		
		// This should not work but its impossible to add any listeners for this.
		// So if you access something by reference be sure not to change it.
		$value = new stdClass();
		$value->name = 'haha';
		$this->assertEqual($value->name, 'haha' );
		$this->assertEqual($item->text->name, 'haha' );
	}
	
	public function testBasic() {
		try {
		
		DomArTestClass_BasicFields::getTable()->update();
		
		$item = new DomArTestClass_BasicFields( 'text', true );
		$this->assertEqual( $item->boolean, true );
		$this->assertEqual( $item->longtext, 'longtext' );
		
		$item->int = 11;
		$item->float = 111.11;
		$item->char = 'char5';
		
		$item->save();
		
		$this->assertObjectDatabaseValue( $item, 'text', 'text' );
		$this->assertObjectDatabaseValue( $item, 'longtext', 'longtext' );
		$this->assertObjectDatabaseValue( $item, 'boolean', 1 );
		$this->assertObjectDatabaseValue( $item, 'bool', 1 );
		$this->assertObjectDatabaseValue( $item, 'int', 11 );
		$this->assertObjectDatabaseValue( $item, 'float', 111.11 );
		$this->assertObjectDatabaseValue( $item, 'char', 'char5' );
		
		$this->assertObjectDatabaseValue( $item, 'className', 'DomArTestClass_BasicFields' );
		// test validators
		
		$item->int = 100;
		$this->assertFalse( $item->validated() );
		$item->setValidated(true);
		
		$item->int = -99;
		$this->assertTrue( $item->validated() );
		$item->setValidated(true);
		
		$item->int = -100;
		$this->assertFalse( $item->validated() );
		$item->setValidated(true);
		
		$item->int = 1111.11;
		$this->assertFalse( $item->validated() );
		$item->setValidated(true);
		
		$item->int = 111.111;
		$this->assertFalse( $item->validated() );
		$item->setValidated(true);
		
		$item->int = 11.111;
		$this->assertFalse( $item->validated() );
		$item->setValidated(true);
		
		$item->float = -111.11;
		$this->assertTrue( $item->validated() );
		$item->setValidated(true);
		
		$item->int = 11.111;
		$this->assertFalse( $item->validated() );
		$item->setValidated(true);
		
		$item->char = 'char5+';
		$this->assertFalse( $item->validated() );
		$item->setValidated(true);
		
		$item->bool = 1;
		$this->assertFalse( $item->validated() );
		$item->setValidated(true);
		
		$item->bool = NULL;
		$this->assertTrue( $item->validated() );
		$item->setValidated(true);
		
		$item->delete();
		} catch( Exception $e) {
			echo exceptionToString($e);
		}
	
	}
	
	public function testOperators() {
		DomArTestClass_BasicFields::getTable()->update();
		
		
		$item = new DomArTestClass_BasicFields( 'text', true );

		$item->int = 11;
		$item->float = 111.11;
		$item->char = 'char5';
		$item->save();
		
		$this->assertEqual( $item->int, 11);
		$item->int += 2;
		$this->assertEqual( $item->int, 13);
		

		$item->int .= 'aa';

		$this->assertFalse( $item->validated() );
		

		$this->assertEqual( $item->array, array() );
		$item->array[] = 'aa';
		$this->assertEqual( $item->array, array() );
		
		//$this->assertEqual( $item->array, array(0=>'aa'));
		//$item->array[2] = 'aa';
		//$this->assertEqual( $item->array, array(0=>'aa',2=>'aa'));

		
		$item->delete();
	}

	public function testDetails() {
		try {
		
		// ---------------------------------------------
		// test constructors, default values, extended methods.
		$a = new DomArParserTest( 'a');
		$this->assertEqual( $a->name, 'a');
		$this->assertEqual( $a->title, 'default title');
		$this->assertEqual( $a->number, 5);
		$this->assertEqual( $a->test(), 'Test');
		
		$b = new DomArParserExtendedTest('b');
		$this->assertEqual( $b->name, 'b');
		$this->assertEqual( $b->title, 'default title');
		$this->assertEqual( $b->number, 5);
		$this->assertEqual( $b->test(), 'Extended');
		
		$c = new DomArParserMoreExtendedTest('c');
		$this->assertEqual( $c->name, 'c');
		$this->assertEqual( $c->title, 'default title');
		$this->assertEqual( $c->number, 5);
		$this->assertEqual( $c->secondNumber, 10);
		$this->assertEqual( $c->test(), 'MoreExtended');
		// ---------------------------------------------
		
		
		} catch( Exception $e) {
			echo exceptionToString($e);
		}
	}
	
	public function testPluginParser() {
		function parsePluginAnnotation( $string ) {
			$anno = DomArAnnotationParser::parse( $string, 'property', 'text-file','0' );
			return $anno[0];
		}

		$p = DomArClassParser::get('DomArParserTest');
		
		$r = new DomArClassParserRecordProperty_Plugin( 'Test', 'public', 'TestPlugin', 'plugin code', parsePluginAnnotation('@orm plugin TestPlugin(arg1,arg2,arg3)
		')  );
		$r->prepare( $p );
		$this->assertEqual($r->createHandlerCode, "new DomArProperty_TestPlugin('TestPlugin','arg1','arg2','arg3')");
		
		
		$r = new DomArClassParserRecordProperty_Plugin( 'Test', 'public', 'TestPlugin', 'plugin code', parsePluginAnnotation('@orm plugin TestPlugin(0,1,2)
		')  );
		$r->prepare( $p );
		$this->assertEqual($r->createHandlerCode, "new DomArProperty_TestPlugin('TestPlugin',0,1,2)");
		
		
		$r = new DomArClassParserRecordProperty_Plugin( 'Test', 'public', 'TestPlugin', 'plugin code', parsePluginAnnotation('@orm plugin TestPlugin({a=b,c})
		')  );
		$r->prepare( $p );
		$this->assertEqual($r->createHandlerCode, "new DomArProperty_TestPlugin('TestPlugin',array('a'=>'b',0=>'c'))");
		
		
		$r = new DomArClassParserRecordProperty_Plugin( 'Test', 'public', 'TestPlugin', 'plugin code', parsePluginAnnotation('@orm plugin TestPlugin({a=b,c,{d=e,f,g,h=i},f},e)
		')  );
		$r->prepare( $p );
		$this->assertEqual($r->createHandlerCode, "new DomArProperty_TestPlugin('TestPlugin',array('a'=>'b',0=>'c',1=>array('d'=>'e',0=>'f',1=>'g','h'=>'i'),2=>'f'),'e')");
		
		
		$r = new DomArClassParserRecordProperty_Plugin( 'Test', 'public', 'TestPlugin', 'plugin code', parsePluginAnnotation('@orm plugin TestPlugin(0002)
		')  );
		$r->prepare( $p );
		$this->assertEqual($r->createHandlerCode, "new DomArProperty_TestPlugin('TestPlugin','0002')");
		
	}
	
	public function testAccess() {
		
		
		
		$a = new DomArTestClass_Access();
		$b = new DomArTestClass_ExtAccess();
		
		// --------------------------------------------
		// TEST A
		// --------------------------------------------
		
		// accessing outside
		$this->assertEqual( $a->public, 'public' );
		try {
			$a->protected;
			$this->assertTrue(true);
		} catch( RuntimeException $e ) {
			$this->assertTrue(false);
		}
		
		try {
			$a->private;
			$this->assertTrue(true);
		} catch( RuntimeException $e ) {
			$this->assertTrue(false);
		}
		
		
		
		// changing from outside
		$a->public = 'public2';
		$this->assertEqual( $a->public , 'public2' );
	
		try {
			$a->protected = 'protected2';
			$this->assertTrue(false);
		} catch( RuntimeException $e ) {
			$this->assertTrue(true);
		}
		
		try {
			$a->private = 'private2';
			$this->assertTrue(false);
		} catch( RuntimeException $e ) {
			$this->assertTrue(true);
		}
	
	
	
		// accessing inside
		$this->assertEqual( $a->accessPublic(), 'public2' );
		$this->assertEqual( $a->accessProtected(), 'protected' );
		$this->assertEqual( $a->accessPrivate(), 'private' );
		
		// changing inside
		$a->updatePublic();
		$this->assertEqual( $a->accessPublic(), 'public3' );
		
		$a->updateProtected();
		$this->assertEqual( $a->accessProtected(), 'protected3' );
		
		$a->updatePrivate();
		$this->assertEqual( $a->accessPrivate(), 'private3' );
	
		
		// --------------------------------------------
		// TEST EXTENDING
		// --------------------------------------------
		
		// accessing outside
		$this->assertEqual( $b->public, 'public' );
		try {
			$b->protected;
			$this->assertTrue(true);
		} catch( RuntimeException $e ) {
			$this->assertTrue(false);
		}
		
		try {
			$b->private;
			$this->assertTrue(true);
		} catch( RuntimeException $e ) {
			$this->assertTrue(false);
		}
		
		
		
		// changing from outside
		$b->public = 'public2';
		$this->assertEqual( $b->public , 'public2' );
	
		try {
			$b->protected = 'protected2';
			$this->assertTrue(false);
		} catch( RuntimeException $e ) {
			$this->assertTrue(true);
		}
		
		try {
			$b->private = 'private2';
			$this->assertTrue(false);
		} catch( RuntimeException $e ) {
			$this->assertTrue(true);
		}
	
	
	
		// accessing inside
		$this->assertEqual( $b->accessPublicExt(), 'public2' );
		$this->assertEqual( $b->accessProtectedExt(), 'protected' );
		$this->assertEqual( $b->accessPrivateExt(), 'private' );
		
		
		// changing inside
		$a->updatePublic();
		$this->assertEqual( $a->accessPublic(), 'public3' );
		
		$a->updateProtected();
		$this->assertEqual( $a->accessProtected(), 'protected3' );
		
		$a->updatePrivate();
		$this->assertEqual( $a->accessPrivate(), 'private3' );
		
		
		// changing inside ext
		$b->updatePublicExt();
		$this->assertEqual( $b->accessPublicExt(), 'public4' );
		
		$b->updateProtectedExt();
		$this->assertEqual( $b->accessProtectedExt(), 'protected4' );
		
		$b->updatePrivateExt();
		$this->assertEqual( $b->accessPrivateExt(), 'private4' );
		
		
	}
	
	public function testInit() {
		
		DomArInitTestClass::getTable()->update();
		
		$a = new DomArInitTestClass();
		$this->assertTrue( $a->initCalled );
		$a->save();
		
		DomAr::flushStoredObjects();
		
		$a = DomArInitTestClass::load( $a->id );
		$this->assertFalse( $a->initCalled );		
	}
	
	public function testInitLoaded() {
		
		DomArInitTestClass::getTable()->update();
		
		$a = new DomArInitTestClass();
		$this->assertFalse( $a->initLoadedCalled );
		$a->save();
		
		DomAr::flushStoredObjects();
		
		$a = DomArInitTestClass::load( $a->id );
		$this->assertTrue( $a->initLoadedCalled );		
	}

	public function testSerialize() {
		DomArTestClass_BasicFields::getTable()->update();
		
		$a = new DomArTestClass_BasicFields('a',true);
		$a->text = 'aa';
		$a->save();
		
		$serialized = $a->serialize();
		$this->assertTrue( is_string($serialized) );
		
		$aBack = DomArTestClass_BasicFields::unserialize( $serialized );
		$this->assertIdentical( $a, $aBack );
		
		$a->text = 'bb';
		$this->assertEqual( $a->text, $aBack->text );
		
		
	}
	
}
?>